import os
import time
from collections import deque
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Optional
import uvicorn

app = FastAPI(title="Directory Traversal API", 
              description="高效遍历Windows系统目录的API服务", 
              version="1.0.0")

class FileInfo(BaseModel):
    path: str
    name: str
    size: int
    is_dir: bool
    modified_time: float
    created_time: float

class TraversalResponse(BaseModel):
    count: int
    total_size: int
    traversal_time: float
    files: List[FileInfo]

def traverse_files(root_dir):
    """
    使用广度优先搜索（BFS）非递归遍历目录中的所有文件（含子目录）
    返回生成器以节省内存并提高效率
    """
    queue = deque([root_dir])
    while queue:
        current_dir = queue.popleft()
        try:
            with os.scandir(current_dir) as entries:
                for entry in entries:
                    if entry.is_dir(follow_symlinks=False):
                        queue.append(entry.path)
                        yield {
                            "path": entry.path,
                            "name": entry.name,
                            "size": 0,
                            "is_dir": True,
                            "modified_time": entry.stat().st_mtime,
                            "created_time": entry.stat().st_ctime
                        }
                    else:
                        stat = entry.stat()
                        yield {
                            "path": entry.path,
                            "name": entry.name,
                            "size": stat.st_size,
                            "is_dir": False,
                            "modified_time": stat.st_mtime,
                            "created_time": stat.st_ctime
                        }
        except PermissionError:
            # 跳过权限不足的目录
            continue
        except OSError as e:
            # 处理其他可能的OS错误
            print(f"Error accessing {current_dir}: {e}")
            continue

@app.get("/traverse", response_model=TraversalResponse, 
         summary="遍历指定目录", 
         description="递归遍历指定目录下的所有文件和子目录")
async def traverse_directory(path: Optional[str] = None):
    """
    遍历指定目录并返回所有文件信息
    
    - **path**: 要遍历的目录路径，默认为当前工作目录
    """
    if path is None:
        path = os.getcwd()
    
    # 验证路径是否存在
    if not os.path.exists(path):
        raise HTTPException(status_code=404, detail="指定路径不存在")
    
    # 验证路径是否为目录
    if not os.path.isdir(path):
        raise HTTPException(status_code=400, detail="指定路径不是目录")
    
    start_time = time.time()
    files = []
    total_size = 0
    
    # 遍历目录并收集文件信息
    for file_info in traverse_files(path):
        files.append(file_info)
        if not file_info["is_dir"]:
            total_size += file_info["size"]
    
    traversal_time = time.time() - start_time
    
    return {
        "count": len(files),
        "total_size": total_size,
        "traversal_time": traversal_time,
        "files": files
    }

@app.get("/", summary="API信息")
async def root():
    return {
        "message": "目录遍历API服务",
        "version": "1.0.0",
        "endpoints": {
            "/traverse": "遍历指定目录下的所有文件和子目录",
            "/docs": "API文档"
        }
    }

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)